package com.hhkj.study.api.user.common.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.hhkj.study.admin.user.entity.User;
import com.hhkj.study.admin.user.service.base.UserService;
import com.hhkj.study.api.user.common.enums.SourceTypeEnum;
import com.hhkj.study.api.user.common.handler.AccountSessionHandler;
import com.hhkj.study.api.user.model.res.ApiCustomerUserBaseRes;
import com.hhkj.study.api.user.model.res.ApiCustomerUserLoginRes;
import com.hhkj.study.api.user.model.res.ApiCustomerUserWxLoginRes;
import com.hhkj.study.common.cache.GlobalCache;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.DictCodeEnum;
import com.ruoyi.framework.login.api.ApiSessionConst;
import com.ruoyi.framework.login.api.ApiSessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * AccountLoginManager
 *
 * @author SERVER
 * @since 2024/4/1 13:24
 */
@Component
public class AccountLoginManager {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private UserService userService;
    @Resource
    private GlobalCache globalCache;

    /**
     * 退出登录
     */
    public void logout() {
        ApiCustomerUserBaseRes currentAccount = AccountSessionHandler.getCurrentAccount();
        if (ObjectUtil.isNull(currentAccount)) {
            return;
        }
        redisCache.deleteObject(currentAccount.getSessionKey());
    }

    /**
     * 更新用户登录信息
     */
    public void updateLogin() {
        ApiCustomerUserBaseRes currentAccount = AccountSessionHandler.getCurrentAccount();
        // 获取用户信息
        User customerUser = userService.getById(currentAccount.getId());
        ApiCustomerUserLoginRes userLoginRes = BeanUtil.toBean(customerUser, ApiCustomerUserLoginRes.class);

        userLoginRes.setSessionKey(currentAccount.getSessionKey());

        redisCache.setCacheObject(
                currentAccount.getSessionKey(),
                userLoginRes,
                ApiSessionConst.SESSION_TIME_OUT,
                TimeUnit.HOURS);
    }

    /**
     * 登录操作
     *
     * @param customerUser 登录操作
     * @param sourceType 登录来源
     * @return 登录结果信息
     */
    public ApiCustomerUserLoginRes doLogin(User customerUser, Integer sourceType) {
        ApiCustomerUserLoginRes userLoginRes = BeanUtil.toBean(customerUser, ApiCustomerUserLoginRes.class);
        userLoginRes.setSessionKey(assignLoginToken(sourceType, customerUser.getId(), userLoginRes));
        return userLoginRes;
    }


    /**
     * 微信方式登录/注册
     * @param customerUser
     * @param sourceType
     * @return
     */
    public ApiCustomerUserWxLoginRes doWxLogin(User customerUser, Integer sourceType) {
        ApiCustomerUserWxLoginRes wxLoginRes = BeanUtil.toBean(customerUser, ApiCustomerUserWxLoginRes.class);
        wxLoginRes.setSessionKey(assignLoginToken(sourceType, customerUser.getId(), wxLoginRes));
        if (SourceTypeEnum.WECHAT_SCAN.getCode().equals(sourceType)) {
            wxLoginRes.setSessionPcKey(assignLoginToken(SourceTypeEnum.WEB.getCode(), customerUser.getId(), wxLoginRes));
        }
        return wxLoginRes;
    }

    /**
     * 根据不同登录来源，返回不同登录标识
     * @param sourceType
     * @param customerUserId
     * @param userLoginRes
     * @return
     */
    private String assignLoginToken(Integer sourceType, Long customerUserId, ApiCustomerUserBaseRes userLoginRes){
        // 登录来源标识
        String sourceLoginFlag = SourceTypeEnum.getByCode(sourceType);
        // 创建键
        String sessionKey = getLoginCacheKey(sourceLoginFlag, customerUserId, false);
        Map<Long, String> dictMap = globalCache.cacheSimpleDictMap(Lists.newArrayList(DictCodeEnum.COURSE_TYPE.getCode()));
        userLoginRes.setSessionKey(sessionKey);
        userLoginRes.setIntentionalExam(dictMap.get(userLoginRes.getIntentionalExamId()));
        // 删除之前登录的设备账号
        redisCache.deleteBatchObject(getLoginCacheKey(sourceLoginFlag, customerUserId, true));
        redisCache.setCacheObject(sessionKey, userLoginRes, ApiSessionConst.SESSION_TIME_OUT, TimeUnit.HOURS);
        return sessionKey;
    }

    /**
     * 生成登录缓存key
     * @param sourceTypeCode
     * @param userId
     * @return
     */
    private static String getLoginCacheKey(String sourceTypeCode, Long userId, boolean isPrefix){
        if (isPrefix) {
            String sessionPrefixKey = ApiSessionUtils.createSessionKey(Constants.CACHE_KEY_PREFIX, sourceTypeCode, userId.toString(), StrUtil.COLON);
            return StrUtil.removeSuffix(sessionPrefixKey, StrUtil.COLON);
        }
        String thirdSessionKey = UUID.randomUUID().toString();
        return ApiSessionUtils.createSessionKey(Constants.CACHE_KEY_PREFIX, sourceTypeCode, userId.toString(), thirdSessionKey);
    }
}
